import { useState, useCallback, useRef } from 'react';

interface StreamingOptions {
  onChunk: (chunk: string) => void;
  onComplete: (fullContent: string) => void;
  onError: (error: Error) => void;
}

interface StreamingHook {
  startStreaming: (params: any) => Promise<void>;
  stopStreaming: () => void;
  isStreaming: boolean;
}

export function useStreaming({ onChunk, onComplete, onError }: StreamingOptions): StreamingHook {
  const [isStreaming, setIsStreaming] = useState(false);
  const abortControllerRef = useRef<AbortController | null>(null);

  const startStreaming = useCallback(async (params: any) => {
    try {
      setIsStreaming(true);
      abortControllerRef.current = new AbortController();

      const response = await fetch('/api/chat/stream', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(params),
        signal: abortControllerRef.current.signal,
      });

      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }

      const reader = response.body?.getReader();
      const decoder = new TextDecoder();
      let fullContent = '';

      if (reader) {
        while (true) {
          const { done, value } = await reader.read();

          if (done) break;

          const chunk = decoder.decode(value, { stream: true });
          const lines = chunk.split('\n').filter(line => line.trim());

          for (const line of lines) {
            if (line.startsWith('data: ')) {
              const data = line.slice(6);
              if (data === '[DONE]') {
                onComplete(fullContent);
                return;
              }

              try {
                const parsed = JSON.parse(data);
                if (parsed.content) {
                  fullContent += parsed.content;
                  onChunk(parsed.content);
                }
              } catch (e) {
                // Ignore JSON parse errors for partial chunks
              }
            }
          }
        }
      }

      onComplete(fullContent);
    } catch (error) {
      if (error instanceof Error && error.name !== 'AbortError') {
        onError(error);
      } else if (error && typeof error === 'object' && 'name' in error && error.name !== 'AbortError') {
        onError(new Error(String(error)));
      }
    } finally {
      setIsStreaming(false);
      abortControllerRef.current = null;
    }
  }, [onChunk, onComplete, onError]);

  const stopStreaming = useCallback(() => {
    if (abortControllerRef.current) {
      abortControllerRef.current.abort();
      abortControllerRef.current = null;
    }
    setIsStreaming(false);
  }, []);

  return {
    startStreaming,
    stopStreaming,
    isStreaming,
  };
}
